﻿using System;
using System.Collections.ObjectModel;
using System.Collections.Specialized;

namespace UtilZ.Dotnet.Ex.Base
{
    /// <summary>
    /// ObservableCollection扩展类
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class ObservableCollectionEx<T> : ObservableCollection<T> where T : class
    {
        /// <summary>
        /// 集合选中项改变通知
        /// </summary>
        private readonly Action<CollectionSelectedItemChangedEventArgs<T>> _selectedItemChanged;


        private T _selectedItem = null;
        /// <summary>
        /// 获取或设置选中项
        /// </summary>
        public T SelectedItem
        {
            get { return _selectedItem; }
            set
            {
                if (_selectedItem == value)
                {
                    return;
                }

                var args = new CollectionSelectedItemChangedEventArgs<T>(_selectedItem, value);
                _selectedItem = value;
                base.OnPropertyChanged(new System.ComponentModel.PropertyChangedEventArgs(nameof(SelectedItem)));
                this._selectedItemChanged?.Invoke(args);
            }
        }


        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="selectedItemChanged">集合选中项改变通知</param>
        public ObservableCollectionEx(Action<CollectionSelectedItemChangedEventArgs<T>> selectedItemChanged)
            : base()
        {
            this._selectedItemChanged = selectedItemChanged;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="e"></param>
        protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
        {
            base.OnCollectionChanged(e);

            switch (e.Action)
            {
                case NotifyCollectionChangedAction.Add:
                    if (this._selectedItem == null)
                    {
                        this.SelectedItem = (T)e.NewItems[0];
                    }
                    break;
                case NotifyCollectionChangedAction.Replace:
                case NotifyCollectionChangedAction.Reset:
                case NotifyCollectionChangedAction.Remove:
                    //if (!this.Contains(this._selectedItem))
                    //{
                    //    this.SelectedItem = null;
                    //}
                    break;
            }
        }
    }

    /// <summary>
    /// 集合选中项改变事件参数
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class CollectionSelectedItemChangedEventArgs<T> : EventArgs
    {
        /// <summary>
        /// 旧选中项
        /// </summary>
        public T OldSelectedItem { get; private set; }

        /// <summary>
        /// 新选中项
        /// </summary>
        public T NewSelectedItem { get; private set; }

        /// <summary>
        /// 构造函数初始化
        /// </summary>
        /// <param name="oldSelectedItem">旧选中项</param>
        /// <param name="newSelectedItem">新选中项</param>
        public CollectionSelectedItemChangedEventArgs(T oldSelectedItem, T newSelectedItem)
        {
            this.OldSelectedItem = oldSelectedItem;
            this.NewSelectedItem = newSelectedItem;
        }
    }
}
